﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
//using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using Microsoft.Phone.Controls;
using Microsoft.Phone.Shell;
using System.Windows.Navigation;
using System.IO.IsolatedStorage;
using System.Windows.Resources;
using System.Windows.Media.Imaging;
using System.IO;
using Microsoft.Xna.Framework.Media;

namespace BootyShaker
{
    public partial class ShakeDesigner : PhoneApplicationPage
    {
        public ShakeDesigner()
        {
            InitializeComponent();
            PhoneApplicationService phoneAppService = PhoneApplicationService.Current;
            phoneAppService.UserIdleDetectionMode = IdleDetectionMode.Disabled;

            //shakePanel = new ShakePanel();
            //canvas.Children.Add(shakePanel);
            // Canvas.SetZIndex(textBlock1, Int16.MaxValue - 1);
            //AccelerometerHelper.Instance.ReadingChanged += new EventHandler<AccelerometerHelperReadingEventArgs>(OnAccelerometerHelperReadingChanged);

            this.shakeImage.Source = App.ShakeImage;
            //fitImage();
            //this.Width = App.ShakeImage.PixelWidth;
            //this.Height = App.ShakeImage.PixelHeight;
            App.shakeObjects = new List<ShakeObject>();
            //canvas.MouseMove += shakeImage_MouseMove;
            //canvas.MouseLeftButtonUp += shakeImage_MouseUp;
            //canvas.MouseLeftButtonDown += shakeImage_MouseDown;
            //shakeImage.ManipulationDelta += new EventHandler<ManipulationDeltaEventArgs>(manipulationDelta);
            //shakeImage.ManipulationStarted += new EventHandler<ManipulationStartedEventArgs>(shakeImage_ManipulationStarted);
            //shakeImage.RenderTransform = new CompositeTransform();
        }

        private void fitImage()
        {
            GeneralTransform gt = canvas.TransformToVisual(Application.Current.RootVisual);


            imgTransform.Rotation = 0;

            double MinScale = Math.Max(Application.Current.RootVisual.RenderSize.Width / this.shakeImage.ActualWidth,
                            Application.Current.RootVisual.RenderSize.Height / this.shakeImage.ActualHeight);
            imgTransform.ScaleX = MinScale;
            imgTransform.ScaleY = MinScale;
            imgTransform.TranslateX = gt.Transform(new Point(0, 0)).X;
            imgTransform.TranslateY = gt.Transform(new Point(0, 0)).Y;
            //        App.ShakeImage
        }

        double initialAngle;
        double initialScale;
        private void OnTap(object sender, GestureEventArgs e)
        {
            imgTransform.TranslateX = imgTransform.TranslateY = 0;
            e.Handled = true;
        }

        private void OnDoubleTap(object sender, GestureEventArgs e)
        {
            imgTransform.ScaleX = imgTransform.ScaleY = 1;
            e.Handled = true;
        }

        private void OnHold(object sender, GestureEventArgs e)
        {
            //imgTransform.TranslateX = imgTransform.TranslateY = 0;
            //imgTransform.ScaleX = imgTransform.ScaleY = 1;
            //imgTransform.Rotation = 0;
            //e.Handled = true;
        }

        private void OnDragStarted(object sender, DragStartedGestureEventArgs e)
        {
            // border.Background = greenBrush;
            e.Handled = true;
        }

        private void OnDragDelta(object sender, DragDeltaGestureEventArgs e)
        {
            imgTransform.TranslateX += e.HorizontalChange;
            imgTransform.TranslateY += e.VerticalChange;
            e.Handled = true;
        }

        private void OnDragCompleted(object sender, DragCompletedGestureEventArgs e)
        {
            // border.Background = normalBrush;
            e.Handled = true;
        }

        private void OnPinchStarted(object sender, PinchStartedGestureEventArgs e)
        {
            //border.Background = redBrush;
            imgTransform.CenterX = (e.GetPosition((UIElement)e.OriginalSource, 0).X + e.GetPosition((UIElement)e.OriginalSource, 1).X) / 2;
            imgTransform.CenterY = (e.GetPosition((UIElement)e.OriginalSource, 0).Y + e.GetPosition((UIElement)e.OriginalSource, 1).Y) / 2;
            initialAngle = imgTransform.Rotation;
            initialScale = imgTransform.ScaleX;


            e.Handled = true;
        }

        private void OnPinchDelta(object sender, PinchGestureEventArgs e)
        {
            imgTransform.Rotation = initialAngle + e.TotalAngleDelta;
            imgTransform.ScaleX = imgTransform.ScaleY = initialScale * e.DistanceRatio;

            e.Handled = true;

        }

        private void OnPinchCompleted(object sender, PinchGestureEventArgs e)
        {
            //border.Background = normalBrush;
            e.Handled = true;
        }

        private void OnFlick(object sender, FlickGestureEventArgs e)
        {
            // flickData.Text = string.Format("{0} Flick: Angle {1} Velocity {2},{3}",
            //  e.Direction, Math.Round(e.Angle), e.HorizontalVelocity, e.VerticalVelocity);
            e.Handled = true;
        }

        private void shakeImage_ManipulationStarted(object sender, System.Windows.Input.ManipulationStartedEventArgs e)
        {
            Image obj = sender as Image;
            CompositeTransform compositeTransform =
              obj.RenderTransform as CompositeTransform;

        }

        private void manipulationDelta(object sender, System.Windows.Input.ManipulationDeltaEventArgs e)
        {
            //ReportEvent("Manipulation Delta Event: ");
            Image obj = sender as Image;
            CompositeTransform compositeTransform =
              obj.RenderTransform as CompositeTransform;

            if ((e.DeltaManipulation.Scale.X > 0) || (e.DeltaManipulation.Scale.Y > 0))
            {
                double ScaleValue = Math.Max(e.DeltaManipulation.Scale.X,
                  e.DeltaManipulation.Scale.Y);
                System.Diagnostics.Debug.WriteLine("Scale Value: " +
                  ScaleValue.ToString());

                //Limit how large
                if ((compositeTransform.ScaleX <= 4d) || (ScaleValue < 1d))
                {
                    if ((obj.ActualWidth * compositeTransform.ScaleX * ScaleValue > Application.Current.RootVisual.RenderSize.Width) &&
                        (obj.ActualHeight * compositeTransform.ScaleY * ScaleValue > Application.Current.RootVisual.RenderSize.Height))
                    {
                        compositeTransform.ScaleX *= ScaleValue;
                        compositeTransform.ScaleY *= ScaleValue;
                        compositeTransform.CenterX = e.ManipulationOrigin.X;
                        compositeTransform.CenterY = e.ManipulationOrigin.Y;
                    }
                    else
                    {
                        double MinScale = Math.Max(Application.Current.RootVisual.RenderSize.Width / obj.ActualWidth,
                            Application.Current.RootVisual.RenderSize.Height / obj.ActualHeight);
                        compositeTransform.ScaleX = MinScale;
                        compositeTransform.ScaleY = MinScale;
                        compositeTransform.CenterX = e.ManipulationOrigin.X;
                        compositeTransform.CenterY = e.ManipulationOrigin.Y;
                    }
                    //    compositeTransform.TranslateX += e.ManipulationOrigin.X;
                    //    compositeTransform.TranslateY += e.ManipulationOrigin.Y;
                }




            }
            System.Diagnostics.Debug.WriteLine("compositeTransform.ScaleX: " +
              compositeTransform.ScaleX);
            System.Diagnostics.Debug.WriteLine("compositeTransform.ScaleY: " +
              compositeTransform.ScaleY);

            GeneralTransform gt = shakeImage.TransformToVisual(Application.Current.RootVisual);
            double tx = e.DeltaManipulation.Translation.X * compositeTransform.ScaleX;
            double ty = e.DeltaManipulation.Translation.Y * compositeTransform.ScaleY;
            Rect r = gt.TransformBounds(new Rect(new Point(0, 0), new Point(obj.ActualWidth, obj.ActualHeight)));
            if (r.Left + tx < 0 && r.Right + tx > Application.Current.RootVisual.RenderSize.Width)
            {
                compositeTransform.TranslateX += tx;

            }
            else
            {

                if (r.Left + tx > 0)
                {
                    compositeTransform.TranslateX -= r.Left;
                }
                if (r.Right + tx < Application.Current.RootVisual.RenderSize.Width)
                {
                    compositeTransform.TranslateX += Application.Current.RootVisual.RenderSize.Width - r.Right;
                }

            }

            if (r.Top + ty < 0 && r.Bottom + ty > Application.Current.RootVisual.RenderSize.Height)
            {

                compositeTransform.TranslateY += ty;
            }
            else
            {
                Rect rr = gt.Inverse.TransformBounds(r);
                if (r.Top + ty > 0)
                {
                    compositeTransform.TranslateY -= r.Top;
                }


                if (r.Bottom + ty < Application.Current.RootVisual.RenderSize.Height)
                {
                    compositeTransform.TranslateY += Application.Current.RootVisual.RenderSize.Height - r.Bottom;
                }
            }
            e.Handled = true;
        }

        //Point ImageDragPoint;
        //bool drag = false;
        //void shakeImage_MouseUp(object sender, MouseButtonEventArgs e)
        //{

        //    shakeImage.ReleaseMouseCapture();
        //    drag = false;

        //}
        //void shakeImage_MouseDown(object sender, MouseButtonEventArgs e)
        //{
        //    shakeImage.CaptureMouse();
        //    ImageDragPoint = e.GetPosition(canvas);
        //    drag = true;
        //}

        //void shakeImage_MouseMove(object sender, MouseEventArgs e)
        //{
        //    Point pnt = e.GetPosition(canvas);
        //    if (drag)
        //    {
        //        Canvas.SetLeft(shakeImage, Canvas.GetLeft(shakeImage) + (pnt.X - ImageDragPoint.X));
        //        Canvas.SetTop(shakeImage, Canvas.GetTop(shakeImage) + (pnt.Y - ImageDragPoint.Y));
        //        ImageDragPoint = pnt;

        //    }
        //}

        double size = 100;
        private void btnAdd_Click(object sender, EventArgs e)
        {
            Point p = new Point(canvas.ActualWidth / 2, canvas.ActualHeight / 2);
            ShakeObject obj = new ShakeObject(p, new Size(size, size), canvas, 100);
            App.shakeObjects.Add(obj);
            canvas.Children.Add(obj);


            // btnAccept.IsEnabled = true;
        }

        private void btnAccept_Click(object sender, EventArgs e)
        {
            GeneralTransform gt = shakeImage.TransformToVisual(Application.Current.RootVisual);

            //foreach (ShakeObject so in App.shakeObjects){
            //    so.LoadImage(App.ShakeImage, this.canvas);
            //}

            //App.testImage = new WriteableBitmap((int)ellipse1.ActualHeight, (int)ellipse1.ActualWidth);

            //App.testImage.Render(ellipse1, new TranslateTransform());
            //App.testImage.Invalidate();


            ////shakeImage.RenderTransform.Transform(topLeft);
            App.gt = canvas.TransformToVisual(Application.Current.RootVisual);
            ////Point topLeft = App.gt.Transform(new Point(0, 0));
            Point topLeft = new Point(0, 0);
            topLeft = imgTransform.Transform(topLeft);
            Point bottomLeft = new Point(0, shakeImage.ActualHeight);
            bottomLeft = imgTransform.Transform(bottomLeft);
            Point topRight = new Point(shakeImage.ActualWidth, 0);
            topRight = imgTransform.Transform(topRight);
            Point bottomRight = new Point(shakeImage.ActualWidth, shakeImage.ActualHeight);
            bottomRight = imgTransform.Transform(bottomRight);

            int minx = (int)Math.Min(Math.Min(topLeft.X, bottomLeft.X), Math.Min(topRight.X, bottomRight.X));
            int maxx = (int)Math.Max(Math.Max(topLeft.X, bottomLeft.X), Math.Max(topRight.X, bottomRight.X));
            int miny = (int)Math.Min(Math.Min(topLeft.Y, bottomLeft.Y), Math.Min(topRight.Y, bottomRight.Y));
            int maxy = (int)Math.Max(Math.Max(topLeft.Y, bottomLeft.Y), Math.Max(topRight.Y, bottomRight.Y));

            int width = maxx - minx;
            int height = maxy - miny;

            CompositeTransform ct = (CompositeTransform)shakeImage.RenderTransform;
            CompositeTransform st = new CompositeTransform();
            st.ScaleX = imgTransform.ScaleX;
            st.ScaleY = imgTransform.ScaleY;

            st.CenterX = shakeImage.ActualWidth / 2;// imgTransform.CenterX;
            st.CenterY = shakeImage.ActualHeight / 2;//imgTransform.CenterY;
            st.Rotation = imgTransform.Rotation;
            st.TranslateX = width/2 - shakeImage.ActualWidth / 2;
            st.TranslateY = height/2 - shakeImage.ActualHeight / 2;


            shakeImage.UpdateLayout();

            App.ShakeImageTransformed = new WriteableBitmap(width, height);
            App.ShakeImageTransformed.Render(shakeImage, st);
            App.ShakeImageTransformed.Invalidate();

            // App.ShakeImageTransformed = new System.Windows.Media.Imaging.WriteableBitmap(shakeImage, imgTransform);
            //App.ShakeImageTransformed.Render(shakeImage, imgTransform);
            //App.ShakeImageTransformed.Invalidate();

            // App.ShakeImageTransformed.Render(shakeImage, new TranslateTransform());
            // SaveImage();



            topLeft = App.gt.Transform (new Point(minx, miny));
            App.ShakeImagePos = new Microsoft.Xna.Framework.Vector2((float)topLeft.X, (float)topLeft.Y);

            NavigationService.Navigate(new Uri("/GamePage.xaml", UriKind.Relative));
        }

        private void SaveImage()
        {
            // Create a file name for the JPEG file in isolated storage.
            String tempJPEG = "TempJPEG";

            // Create a virtual store and file stream. Check for duplicate tempJPEG files.
            var myStore = IsolatedStorageFile.GetUserStoreForApplication();
            if (myStore.FileExists(tempJPEG))
            {
                myStore.DeleteFile(tempJPEG);
            }

            IsolatedStorageFileStream myFileStream = myStore.CreateFile(tempJPEG);


            // Create a stream out of the sample JPEG file.
            // For [Application Name] in the URI, use the project name that you entered 
            // in the previous steps. Also, TestImage.jpg is an example;
            // you must enter your JPEG file name if it is different.




            WriteableBitmap wb = App.ShakeImageTransformed;

            // Encode the WriteableBitmap object to a JPEG stream.
            wb.SaveJpeg(myFileStream, wb.PixelWidth, wb.PixelHeight, 0, 85);
            myFileStream.Close();

            // Create a new stream from isolated storage, and save the JPEG file to the media library on Windows Phone.
            myFileStream = myStore.OpenFile(tempJPEG, FileMode.Open, FileAccess.Read);

            // Save the image to the camera roll or saved pictures album.
            MediaLibrary library = new MediaLibrary();


            // Save the image to the saved pictures album.
            Picture pic = library.SavePicture("SavedPicture.jpg", myFileStream);
            MessageBox.Show("Image saved to saved pictures album");


            myFileStream.Close();
        }

        protected override void OnNavigatedTo(NavigationEventArgs e)
        {

            // System.Windows.Input.Touch.FrameReported += new TouchFrameEventHandler(Touch_FrameReported);
        }
        protected override void OnNavigatedFrom(NavigationEventArgs e)
        {
            // System.Windows.Input.Touch.FrameReported -= Touch_FrameReported;
        }
        bool scaling = false;
        Point scalepointA;
        Point scalepointB;
        float LastDistance;







        void Touch_FrameReported(object sender, System.Windows.Input.TouchFrameEventArgs e)
        {
            foreach (ShakeObject obj in App.shakeObjects)
            {
                System.Windows.Input.TouchPointCollection tpc = e.GetTouchPoints(obj.mainellipse);
                if (tpc.Count == 2)
                {

                    if (scaling)
                    {
                        scalepointA = tpc[0].Position;
                        scalepointB = tpc[1].Position;
                        double wdt = obj.Width * Distance(scalepointA, scalepointB) / LastDistance;
                        double hgt = obj.Height * Distance(scalepointA, scalepointB) / LastDistance;
                        if (wdt > 50)
                            obj.Width = wdt;
                        else obj.Width = 50;
                        if (hgt > 50)
                            obj.Height = hgt;
                        else obj.Height = 50;
                    }
                    else
                    {
                        scaling = true;
                        scalepointA = tpc[0].Position;
                        scalepointB = tpc[1].Position;
                        LastDistance = Distance(scalepointA, scalepointB);
                    }
                    //if ((InDrawingMode) && (p.Action == TouchAction.Move))
                    //{
                    //    Ellipse ellipse = new Ellipse();
                    //    ellipse.SetValue(Canvas.LeftProperty, p.Position.X);
                    //    ellipse.SetValue(Canvas.TopProperty, p.Position.Y);
                    //    ellipse.Width = _touchRadius;
                    //    ellipse.Height = _touchRadius;
                    //    ellipse.IsHitTestVisible = false;
                    //    ellipse.Stroke = ((ColorClass)ColorListBox.SelectedItem).ColorBrush;
                    //    ellipse.Fill = ((ColorClass)ColorListBox.SelectedItem).ColorBrush;
                    //    DrawCanvas.Children.Add(ellipse);
                    //}

                }
                else scaling = false;
            }
        }
        public float Distance(Point A, Point B)
        {
            return (float)Math.Sqrt(Math.Pow((double)(A.X - B.X), 2) + Math.Pow((double)(A.Y - B.Y), 2));
        }

        private void btnReset_Click(object sender, EventArgs e)
        {
            foreach (ShakeObject obj in App.shakeObjects)
            {
                canvas.Children.Remove(obj);
            }
            App.shakeObjects.Clear();
            fitImage();
        }
    }
}